package net.zio.kamenriderzioaddon.ridersystem.util;

import net.minecraft.ChatFormatting;
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.resources.ResourceLocation;
import net.zio.kamenriderzioaddon.enums.HenshinState;
import net.zio.kamenriderzioaddon.network.NetworkHandler;
import net.zio.kamenriderzioaddon.network.message.AnimationMessage;
import net.zio.kamenriderzioaddon.ridersystem.data.PlayerDataManager;

import java.util.Map;
import java.util.HashMap;
import java.util.UUID;

public class HenshinUtils {
    // 存储每个玩家当前播放的声音
    private static final Map<UUID, SoundEvent> PLAYING_SOUNDS = new HashMap<>();

    public static final EquipmentSlot[] ARMOR_SLOTS = {
            EquipmentSlot.HEAD,
            EquipmentSlot.CHEST,
            EquipmentSlot.LEGS,
            EquipmentSlot.FEET
    };

    public static final EquipmentSlot MAINHAND_SLOT = EquipmentSlot.MAINHAND;
    public static final EquipmentSlot OFFHAND_SLOT = EquipmentSlot.OFFHAND;



    /* -------------装备操纵-------------- */
    /**
     * 检查玩家是否持有指定的主副手道具
     *
     * @param player 玩家实例
     * @param mainItem 主手道具（可为空）
     * @param offhandItem 副手道具（可为空）
     * @return 如果玩家持有指定的主副手道具，返回 true；否则返回 false
     */
    public static boolean isHoldingItems(Player player, Item mainItem, Item offhandItem) {
        ItemStack mainHand = player.getMainHandItem();
        ItemStack offHand = player.getOffhandItem();

        // 检查主手
        if (mainItem != null && !mainHand.getItem().equals(mainItem)) {
            return false;
        }

        // 检查副手
        return offhandItem == null || offHand.getItem().equals(offhandItem);
    }

    /**
     * 移除主手物品
     *
     * @param player 玩家实例
     * @param item 要移除的物品
     */
    public static void removeMainhandItem(Player player, Item item) {
        ItemStack mainHandStack = player.getMainHandItem();
        if (!mainHandStack.isEmpty() && mainHandStack.getItem() == item) {
            if (mainHandStack.getCount() > 1) {
                mainHandStack.shrink(1);
            } else {
                player.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
            }
        } else {
            // 如果主手不是指定物品，尝试从背包中移除
            removeItemFromInventory(player, item);
        }
    }

    /**
     * 移除副手物品
     *
     * @param player 玩家实例
     * @param item 要移除的物品
     */
    public static void removeOffhandItem(Player player, Item item) {
        ItemStack offHandStack = player.getOffhandItem();
        if (!offHandStack.isEmpty() && offHandStack.getItem() == item) {
            if (offHandStack.getCount() > 1) {
                offHandStack.shrink(1);
            } else {
                player.setItemSlot(EquipmentSlot.OFFHAND, ItemStack.EMPTY);
            }
        } else {
            // 如果副手不是指定物品，尝试从背包中移除
            removeItemFromInventory(player, item);
        }
    }

    /**
     * 移除所有手持物品
     *
     * @param player 玩家实例
     * @param mainItem 主手物品
     * @param offhandItem 副手物品
     */
    public static void removeAllHeldItems(Player player, Item mainItem, Item offhandItem) {
        removeMainhandItem(player, mainItem);
        removeOffhandItem(player, offhandItem);
    }

    /**
     * 从背包中移除指定物品
     *
     * @param player 玩家实例
     * @param item 要移除的物品
     */
    private static void removeItemFromInventory(Player player, Item item) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack stack = player.getInventory().getItem(i);
            if (!stack.isEmpty() && stack.getItem() == item) {
                if (stack.getCount() > 1) {
                    stack.shrink(1);
                } else {
                    player.getInventory().setItem(i, ItemStack.EMPTY);
                }
                return; // 移除一个后返回
            }
        }
    }

    // 保存玩家装备（包括主副手）
    public static CompoundTag savePlayerGear(Player player) {
        CompoundTag gearData = new CompoundTag();

        // 保存盔甲
        for (int i = 0; i < ARMOR_SLOTS.length; i++) {
            ItemStack stack = player.getItemBySlot(ARMOR_SLOTS[i]);
            CompoundTag slotTag = new CompoundTag();
            if (!stack.isEmpty()) {
                stack.save(slotTag);
            }
            gearData.put("slot" + i, slotTag);
        }

        // 保存主手物品
        ItemStack mainHand = player.getMainHandItem();
        if (!mainHand.isEmpty()) {
            CompoundTag mainHandTag = new CompoundTag();
            mainHand.save(mainHandTag);
            gearData.put("mainhand", mainHandTag);
        }

        // 保存副手物品
        ItemStack offHand = player.getOffhandItem();
        if (!offHand.isEmpty()) {
            CompoundTag offHandTag = new CompoundTag();
            offHand.save(offHandTag);
            gearData.put("offhand", offHandTag);
        }

        return gearData;
    }

    /**
     * 获取玩家待机前存储的装备
     *
     * @param player 玩家实例
     * @return 备用装备数据
     */
    public static   CompoundTag getStandbyGear(Player player) {
        return PlayerDataManager.get(player).getStandbyGear();
    }

    /**
     * 获取玩家变身前装备
     *
     * @param player 玩家实例
     * @return 当前装备数据
     */
    public static CompoundTag getActiveGear(Player player) {
        return PlayerDataManager.get(player).getActiveGear();
    }

    /**
     * 恢复待机状态装备
     */
    public static void restoreStandbyGear(Player player) {
        CompoundTag standbyGear = HenshinUtils.getStandbyGear(player);
        System.out.println("还原时待机物品"+standbyGear);
        if (standbyGear != null) {
            if (standbyGear.contains("legs")) {
                player.setItemSlot(EquipmentSlot.LEGS,
                        ItemStack.of(standbyGear.getCompound("legs")));
            }
            if (standbyGear.contains("mainhand")) {
                restoreItemToSlot(player, EquipmentSlot.MAINHAND, ItemStack.of(standbyGear.getCompound("mainhand")));
            }
            if (standbyGear.contains("offhand")) {
                restoreItemToSlot(player, EquipmentSlot.OFFHAND, ItemStack.of(standbyGear.getCompound("offhand")));
            }
        }
    }

    /**
     * 恢复玩家全部的装备
     *
     * @param player 玩家实例
     */
    public static void restorePlayerGear(Player player) {
        CompoundTag activeGear = PlayerDataManager.get(player).getActiveGear();

        if (activeGear.contains("head")) {
            player.setItemSlot(EquipmentSlot.HEAD,
                    ItemStack.of(activeGear.getCompound("head")));
        }
        if (activeGear.contains("chest")) {
            player.setItemSlot(EquipmentSlot.CHEST,
                    ItemStack.of(activeGear.getCompound("chest")));
        }
        if (activeGear.contains("feet")) {
            player.setItemSlot(EquipmentSlot.FEET,
                    ItemStack.of(activeGear.getCompound("feet")));
        }

        restoreStandbyGear(player);
    }

    /**
     * 恢复物品到指定槽位
     *
     * @param player 玩家实例
     * @param slot 装备槽位
     * @param item 要恢复的物品
     */
    private static void restoreItemToSlot(Player player, EquipmentSlot slot, ItemStack item) {
        if (item.isEmpty()) return;

        // 如果槽位为空，直接放置
        if (player.getItemBySlot(slot).isEmpty()) {
            player.setItemSlot(slot, item);
            return;
        }

        // 尝试放入背包
        if (player.getInventory().add(item)) {
            return;
        }

        // 背包满了则生成掉落物
        if (player.level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
            player.spawnAtLocation(item);
        }
    }

    /**
     * 检查玩家是否装备了全套盔甲
     *
     * @param player 玩家实例
     * @param armorSet 盔甲数组
     * @return 如果玩家装备了全套盔甲，返回 true；否则返回 false
     */
    public static boolean isFullyEquipped(Player player, Item[] armorSet) {
        for (int i = 0; i < ARMOR_SLOTS.length; i++) {
            ItemStack stack = player.getItemBySlot(ARMOR_SLOTS[i]);
            if (stack.isEmpty() || stack.getItem() != armorSet[i]) {
                return false;
            }
        }
        return true;
    }

        /**
     * 检查玩家是否装备了对应的盔甲
     *
     * @param player 玩家实例
     * @param armorSet 盔甲数组
     * @return 如果玩家装备了对应的头盔、胸甲和鞋子，返回 true；否则返回 false
     */
    public static boolean isEquippedArmor(Player player, Item[] armorSet) {
        // 定义需要检查的装备槽位：头盔、胸甲、鞋子
        EquipmentSlot[] relevantSlots = {EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.FEET};
        // 对应需要检查的盔甲数组索引
        int[] armorIndices = {0, 1, 3};

        for (int i = 0; i < relevantSlots.length; i++) {
            ItemStack stack = player.getItemBySlot(relevantSlots[i]);
            if (stack.isEmpty() || stack.getItem() != armorSet[armorIndices[i]]) {
                return false;
            }
        }
        return true;
    }





    // 播放音效（跟随玩家，通知附近玩家）
    public static void playSound(Player player, SoundEvent sound) {
        if (sound == null) {
            return;
        }

        Level world = player.level;
        if (!world.isClientSide) {
            // 在玩家位置播放声音，使用PLAYERS音源，让附近玩家都能听到
            world.playSound(
                    null, // 没有特定来源
                    player.getX(), player.getY(), player.getZ(), // 玩家位置
                    sound,
                    SoundSource.PLAYERS, // 玩家音源
                    1.0F, // 音量
                    1.0F  // 音调
            );

            // 记录当前播放的声音
            PLAYING_SOUNDS.put(player.getUUID(), sound);
        }
    }

    // 停止特定声音
    public static void stopSound(Player player, SoundEvent sound) {
        if (sound == null || !(player instanceof ServerPlayer serverPlayer)) {
            return;
        }

        ResourceLocation soundLocation = sound.getLocation();

        // 发送停止声音的数据包
        serverPlayer.connection.send(new ClientboundStopSoundPacket(
                soundLocation,
                SoundSource.PLAYERS
        ));

        // 从记录中移除
        PLAYING_SOUNDS.remove(player.getUUID());
    }


    // 发送消息给玩家
    public static void sendMessage(Player player, String message, net.minecraft.ChatFormatting color) {
        player.displayClientMessage(new net.minecraft.network.chat.TextComponent(message).withStyle(color), true);
    }

    /**
     * 发送配置消息给玩家
     *
     * @param player 玩家实例
     * @param riderName 骑士名称
     * @param message 消息内容
     */
    public static void sendConfigMessage(Player player,
                                         String riderName,
                                         String message) {
        String formatted = String.format("[%s] %s", riderName, message);
        sendMessage(player, formatted, ChatFormatting.GOLD);
    }

    // 发送动画消息
    public static void sendAnimationMessage(Player player, String animationName) {
        if (player instanceof ServerPlayer sp) {
            NetworkHandler.sendToTrackingPlayers(
                    new AnimationMessage(animationName, player.getUUID(), true),
                    sp
            );
        }
    }

    /**
     * 清除玩家的装备数据。
     *
     * @param player 玩家实例
     */
    public static void clearGearData(Player player) {
        PlayerDataManager.get(player).clearGearData();
    }


}